package com.luych.toolbox.data.service.core.dm;

import com.luych.toolbox.common.enums.CaseType;
import com.luych.toolbox.common.enums.DataSourceType;
import com.luych.toolbox.data.service.core.CoreBuilder;
import com.luych.toolbox.data.service.core.CoreColumn;
import org.apache.commons.lang.RandomStringUtils;

public class DmColumn implements CoreColumn {

    private final String owner;
    private final String name;
    private final DmDataType dataType;
    private final Long charLength;
    private final Long numericPrecision;
    private final Long numericScale;
    private final Boolean nullable;
    private final String comment;
    private final Boolean increment;

    public DmColumn(CoreColumn coreColumn) {
        this.owner = coreColumn.getOwner();
        this.name = coreColumn.getName();
        this.dataType = (DmDataType) CoreBuilder.buildDataType(coreColumn.getDataSourceType(), DataSourceType.DM, coreColumn.getDataType());
        this.charLength = coreColumn.getCharLength();
        this.numericPrecision = coreColumn.getNumericPrecision();
        this.numericScale = coreColumn.getNumericScale();
        this.nullable = coreColumn.isNullable();
        this.comment = coreColumn.getComment();
        this.increment = coreColumn.isIncrement();
    }

    public DmColumn(String owner, String name, DmDataType dataType, Long charLength, Long numericPrecision, Long numericScale, Boolean nullable, String comment, Boolean increment) {
        this.owner = owner;
        this.name = name;
        this.dataType = dataType;
        this.charLength = charLength;
        this.numericPrecision = numericPrecision;
        this.numericScale = numericScale;
        this.nullable = nullable;
        this.comment = comment;
        this.increment = increment;
    }

    @Override
    public DataSourceType getDataSourceType() {
        return DataSourceType.DM;
    }

    @Override
    public String getOwner() {
        return owner;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public DmDataType getDataType() {
        return dataType;
    }

    @Override
    public Long getCharLength() {
        return charLength;
    }

    @Override
    public Long getNumericPrecision() {
        return numericPrecision;
    }

    @Override
    public Long getNumericScale() {
        return numericScale;
    }

    @Override
    public Boolean isNullable() {
        return nullable;
    }

    @Override
    public String getComment() {
        return comment;
    }

    @Override
    public Boolean isIncrement() {
        return increment;
    }

    @Override
    public String getCreateSql(CaseType caseType) {
        String tableName = caseType.getConvert().apply(this.getOwner());
        String columnName = caseType.getConvert().apply(this.getName());

        tableName = "\"" + tableName + "\"";
        columnName = "\"" + columnName + "\"";

        String sql = "ALTER TABLE " + tableName + " ADD COLUMN " + columnName + " " + this.getColumnType();
        if (this.isIncrement()) {
            sql += " IDENTITY(1, 1)";
        }
        if (this.isNullable()) {
            sql += " NULL";
        } else {
            sql += " NOT NULL";
        }
        sql += ";";
        sql += "\r\nCOMMENT ON COLUMN " + tableName + "." + columnName + " IS '" + this.getComment() + "';";
        return sql;
    }

    @Override
    public String getModifySql(CaseType caseType) {
        String tableName = caseType.getConvert().apply(this.getOwner());
        String columnName = caseType.getConvert().apply(this.getName());

        tableName = "\"" + tableName + "\"";
        columnName = "\"" + columnName + "\"";

        if (DmDataType.TEXT.name().equals(this.getDataType().getName())) {
            String randomName = "\"" + caseType.getConvert().apply(RandomStringUtils.randomAlphabetic(10)) + "\"";
            String sql = "ALTER TABLE " + tableName + " RENAME COLUMN " + columnName + " TO " + randomName + ";";
            sql += "\r\nALTER TABLE " + tableName + " ADD " + columnName + " " + this.getColumnType();
            if (this.isIncrement()) {
                sql += " IDENTITY(1, 1)";
            }
            if (this.isNullable()) {
                sql += " NULL";
            } else {
                sql += " NOT NULL";
            }
            sql += ";";
            sql += "\r\nCOMMENT ON COLUMN " + tableName + "." + columnName + " IS '" + this.getComment() + "';";
            sql += "\r\nUPDATE " + tableName + " SET " + columnName + " = " + randomName + "; COMMIT;";
            sql += "\r\nALTER TABLE " + tableName + " DROP " + randomName + " CASCADE;";
            return sql;
        } else {
            String sql = "ALTER TABLE " + tableName + " MODIFY " + columnName + " " + this.getColumnType();
            if (this.isIncrement()) {
                sql += " IDENTITY(1, 1)";
            }
            if (this.isNullable()) {
                sql += " NULL";
            } else {
                sql += " NOT NULL";
            }
            sql += ";";
            sql += "\r\nCOMMENT ON COLUMN " + tableName + "." + columnName + " IS '" + this.getComment() + "';";
            return sql;
        }
    }

    @Override
    public String getRemoveSql(CaseType caseType) {
        String tableName = caseType.getConvert().apply(this.getOwner());
        String columnName = caseType.getConvert().apply(this.getName());

        tableName = "\"" + tableName + "\"";
        columnName = "\"" + columnName + "\"";

        return "ALTER TABLE " + tableName + " DROP COLUMN " + columnName + ";";
    }
}
